#!/usr/bin/python2
# -*- coding: utf-8 -*-

from PySide import QtCore, QtGui, QtWebKit
import re, os, sys, random, base64
from dialogs import MyErrorDialog
from myreq import NetworkAccessManager
import sdfviewer_rc
from jquery import jquery
from .. mol import Mol2pic, sdf2list, smi_filter

try:
    from .. utils import tr
except:
    tr = lambda msg: msg

def uri_b64encode(s):
    return base64.urlsafe_b64encode(s).strip('=')

def TableJS(data_dic):
    tpl = '''$(function(){
                table = new TableView('%(table_div)s');
                table.header = %(header)s;
                table.dataKey = '%(primary_key)s';
                table.pager.size = %(pager_size)s;
                table.addRange(%(data_list)s);
                table.display.marker = true;
                table.display.multiple = false;
                table.display.filter = true;
                table.display.pager = true;
                table.render();});'''

    for k in ('table_div', 'header', 'primary_key', 'pager_size', 'data_list'):
        if not data_dic.has_key(k):
            return ''
        else:
            data_dic[k] = str(data_dic[k])
    return tpl %data_dic

class PythonJS(QtCore.QObject):
    contentChanged = QtCore.Signal(str, str)
    @QtCore.Slot(str, str)
    def handler(self, msg_type, msg):
        self.contentChanged.emit(msg_type, msg)

class SdfViewer(QtWebKit.QWebView):
    def __init__(self, sdfviewer_url, parent = None, pager_size = 20):
        QtWebKit.QWebView.__init__(self)
        if parent is None:
            self.parent = object()
        else:
            self.parent = parent
        self.resize(700, 400)
        self.sdf_string = ''
        self.error_dialog = MyErrorDialog()
        self.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
        self.file_selector = QtGui.QFileDialog(self)
        self.prev_mols = []
        self.pager_size = pager_size
        pjs = PythonJS()

        old_manager = self.page().networkAccessManager()
        new_manager = NetworkAccessManager(old_manager)
        self.page().setNetworkAccessManager(new_manager)

        self.load(QtCore.QUrl(sdfviewer_url))
        self.mainframe = self.page().mainFrame()
        self.document = self.mainframe.documentElement()
        self.mainframe.addToJavaScriptWindowObject("python", pjs)

        self.mainframe.evaluateJavaScript(jquery)

        self.parent.last_sdf_file_dir = '.'

        # signals
        pjs.contentChanged.connect(self.jshandler)

    def set_title(self, title):
        self.setWindowTitle(title)

    def set_data(self, sdf_string):
        self.sdf_string = sdf_string
        mol_list = sdf2list(sdf_string, smi_filter)
        lst = self.format_sdflist(mol_list)
        js = TableJS({
            'table_div': 'table_div',
            'header': '''{
                    struc: '%(structure)s',
                    id : '%(cid)s',
                    exact_mass : '%(exact_mass)s',
                    fm: '%(formula)s',
                    pubchem_link_html: '%(pubchem_link_html)s',
                }''' %{
                    'structure': tr('Structure'),
                    'cid': tr('CID'),
                    'exact_mass': tr('Exact mass'),
                    'formula': tr('Formula'),
                    'pubchem_link_html': tr('PubChem link'),
                    },
            'primary_key': 'id',
            'pager_size': self.pager_size,
            'data_list': lst
            })
        self.mainframe.evaluateJavaScript(js)

    def format_sdflist(self, sdflist):
        result_list = []
        tpl = '''{id: '%(id)s', struc: '%(struc)s', exact_mass: '%(exact_mass)s', fm: '%(fm)s', larger_img: '%(larger_img)s', pubchem_link: '%(pubchem_link)s', pubchem_link_html: '%(pubchem_link_html)s'}'''
        for d in sdflist:
            if d.has_key('mol_id'):
                file_id = d['mol_id']
                pubchem_link = "http://pubchem.ncbi.nlm.nih.gov/summary/summary.cgi?cid=%s" %d['mol_id']
            else:
                file_id = str(random.random()).replace('.', '')
                d['mol_id'] = 'None'
                pubchem_link = 'None'

            if d.has_key('mol_2d_struc'):
                img_url = 'myreq://handler?do=svg&mol=%s&weight=600&height=600' %uri_b64encode(d['mol_2d_struc'])

            if d.has_key('PUBCHEM_EXACT_MASS'):
                exact_mass = d['PUBCHEM_EXACT_MASS']

            if d.has_key('PUBCHEM_MOLECULAR_FORMULA'):
                fm = d['PUBCHEM_MOLECULAR_FORMULA']

            result_list.append(tpl %{
                'id': file_id,
                'struc': '''<img src="%s" height="100" width="100" alt="%s"/>''' %(img_url, file_id),
                'exact_mass': exact_mass,
                'fm': fm,
                'pubchem_link':  pubchem_link,
                'pubchem_link_html':  '<a href="%s" target="_blank">%s</a>' %(pubchem_link, tr('Click me')),
                'larger_img': img_url,
                })
        return '[%s]' %',\n'.join(result_list)

    def jshandler(self, type, msg):
        if type == 'get_data':
            cid, link, img = msg.split('|')
            id = str(random.random()).replace('.', '')
            js = '''createDiv('%s', '%s');
                easyDialog.open({
                    container: "%s",
                    fixed: false,
                    header: 'hello',
                    });''' %(id, '''<table border="2" style="text-align: center"><tr><td>CID: %s \
                            <img align="right" src="images/close.png" id="closeBtn"/></td></tr> \
                            <tr><td><img src="%s" id="%s" height="%s" width="%s"/></td></tr> \
                            <tr><td><a href="%s" target="_blank">%s</a></td></tr>''' %(cid, img, 'closeBtn', 300, 300, link, tr('Search PubChem')), id)
            self.mainframe.evaluateJavaScript(js)
        elif type == 'search':
            print msg
        elif type == 'save_sdf' and self.sdf_string != '':
            file_name = self.file_selector.getSaveFileName(self,
            tr('Save to SDF file'),
            self.parent.last_sdf_file_dir,
            tr('*.sdf (SDF file)(*.sdf);;*.* (All types of file)(*)'))[0]
            if file_name != '':
                self.parent.last_sdf_file_dir = os.path.dirname(file_name)
                if not file_name.endswith('.sdf'):
                    file_name = file_name + '.sdf'
                try:
                    open(file_name, 'w').write(self.sdf_string)
                except Exception, e:
                    print e
        elif type == 'load_sdf':
            file_name = self.file_selector.getOpenFileName(self,
            tr('Load SDF file'),
            self.parent.last_sdf_file_dir,
            tr('*.sdf (SDF file)(*.sdf);;*.* (All types of file)(*)'))[0]
            if file_name != '':
                self.parent.last_sdf_file_dir = os.path.dirname(file_name)
                try:
                    self.set_data(open(file_name, 'r').read())
                    self.parent.set_title(os.path.basename(file_name))
                except Exception, e:
                    print e


class SdfForm(QtGui.QMainWindow):
    def __init__(self, url = 'qrc:/html/sdfviewer.html', sdf_string = '',
            load_on_init = True, parent = None):
        '''url: init url, sdf_string: contents of the sdf file to show,
        load_on_init: load the url on class init? parent: parent of this widget.'''
        QtGui.QMainWindow.__init__(self, parent)

        self.sdf_string = sdf_string
        self.tabWidget = None
        self.view = None
        self.idx = 0
        self.url = url
        if load_on_init:
            self.loadUrl(QtCore.QUrl(url))
        if sdf_string and self.view:
            self.set_data(sdf_string)

    def init_tab(self):
        self.tabWidget = QtGui.QTabWidget(self)
        self.tabWidget.setTabsClosable(True)
        self.setCentralWidget(self.tabWidget)
        self.tabWidget.tabCloseRequested.connect(self.close_tab)

    def set_title(self, title):
        if self.tabWidget:
            self.tabWidget.setTabText(self.tabWidget.currentIndex(), title)

    def close_tab(self, idx):
        self.tabWidget.removeTab(idx)

    def set_data(self, sdf_string):
        if self.view:
            self.view.set_data(sdf_string)
            self.tabWidget.setCurrentIndex(self.tabWidget.count() - 1)

    def add_view(self, url = '', title = tr('Viewer')):
        u = url and url or self.url
        if url == '_blank':
            u = QtCore.QUrl('qrc:/html/blank.html')
        if not self.tabWidget:
            self.init_tab()
        self.view = SdfViewer(u, self)
        self.view.linkClicked.connect(self.linkClicked)
        self.view.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateAllLinks)
        self.tabWidget.setCurrentIndex(self.tabWidget.addTab(self.view, title))

    def loadUrl(self, url = ''):
        if url != '':
            if not self.tabWidget:
                self.init_tab()
            title = tr('Viewer')
            try:
                l = url.toString().split('cid=')
                title = '[CID: %s]' %l[1]
            except Exception, e:
                sys.stderr.write(str(e))
            self.add_view(url, title)

    def linkClicked(self, url):
        self.loadUrl(url)

if __name__=='__main__':
    try:
        import sys, os
        app = QtGui.QApplication(sys.argv)

        browser = SdfForm(load_on_init = False)#'qrc:/html/sdfviewer.html')
        fn = 'tst.sdf'
        browser.add_view()
        browser.set_data(open(fn).read())
        browser.set_info('hhhhhhhhhhh')
        #browser.set_title('hhh')
        #browser.add_view('_blank')
        browser.show()
    except Exception, e:
        print e
        raw_input()

    sys.exit(app.exec_())
